package org.jxkj.webapi;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.jxkj.bean.PointData;
import org.jxkj.utils.ParseUtils;
import org.jxkj.utils.StringUtils;

import java.io.InputStream;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 调用逻辑分析
 * FormaluPoint中调用使用
 *    |-DftoMap
 *       |- insertFormula2Hbase ->公式计算存hbase [不在使用，在calcstat中实现]
 *       |- insertFormula2Mysql ->智能抄表算法 调用
 */
public class WebAPI {
    private static String URL_GETHISTSNAP = null;
    private static String URL_GETHISTRAW = null;
    private static String URL_GETHISTSTATTYPE = null;
    private static HttpClient httpClient;

    private static final Logger logger = Logger.getLogger(WebAPI.class);

    public WebAPI() {
        try {
            if (URL_GETHISTSNAP == null) {
                Properties prop = new Properties();
                InputStream is = ClassLoader.getSystemResourceAsStream("env.properties");
                prop.load(is);
                String webapi = prop.getProperty("webapi.url");
                URL_GETHISTSNAP = webapi + "/hmsapi/invoke/edos/GetHistSnap";
                URL_GETHISTRAW = webapi + "/hmsapi/invoke/edos/GetHistRaw";
                URL_GETHISTSTATTYPE = webapi + "/hmsapi/invoke/edos/GetHistStatType";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        httpClient = HttpClients.createDefault();
    }


    /**
     * 获得历史数据的方法
     *
     * @param pointName
     * @param starTime
     * @param endTime
     * @return
     */
    public List<PointData> getHistRaw(String pointName, String starTime, String endTime) throws Exception {
        HashMap<String, String> map = new HashMap<>();
        map.put("pointId", pointName);
        map.put("start", ParseUtils.getTimestamp(starTime) + "");
        map.put("end", ParseUtils.getTimestamp(endTime) + "");
        String content = httpGet(map, URL_GETHISTRAW);
        return json2PointData(content, pointName);
    }


    /**
     * 获得历史快照的方法
     *
     * @param pointName
     * @param starTime
     * @param endTime
     * @param period
     * @throws Exception
     */
    public List<PointData> getHistSnap(String pointName, String starTime, String endTime, String period) throws Exception {
        HashMap<String, String> map = new HashMap<>();
        map.put("pointId", pointName);
        map.put("start", ParseUtils.getTimestamp(starTime) + "");
        map.put("end", ParseUtils.getTimestamp(endTime) + "");


        if ("GZB_TD_AI00001".equals(pointName)) {
            map.put("period", 900 + "");
            //这里要多等比计算
            String content = httpGet(map, URL_GETHISTSNAP);
            List<PointData> list = json2PointData(content, pointName);

            //这里加一秒，用来特殊用
            HashMap<String, String> _map = new HashMap<>();
            _map.put("pointId", pointName);
            _map.put("start", ParseUtils.getTimestamp(endTime) + "");
            _map.put("end", (ParseUtils.getTimestamp(endTime) + 1) + "");

            String _content = httpGet(_map, URL_GETHISTSNAP);
            List<PointData> listByLast = json2PointData(_content, pointName);

            list.addAll(listByLast);

            //这里要多等比计算
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            List<PointData> equalList = new ArrayList<PointData>();
            for (int i = 0; i < list.size(); i++) {
                if (i == 0) {
                    equalList.add(list.get(i));
                } else if (i >= 1) {
                    double equalValue = (Double.parseDouble(list.get(i).getValue()) - Double.parseDouble(list.get(i - 1).getValue())) / 3;
                    for (int j = 1; j < 3; j++) {
                        Date t = sdf.parse(list.get(i - 1).getTime());
                        Long time = t.getTime() + j * 300 * 1000;
                        Double value = Double.parseDouble(list.get(i - 1).getValue()) + equalValue * j;

                        Date _date = new Date(time);
                        String _time = sdf.format(_date);

                        PointData pointData = new PointData();
                        pointData.setName(pointName);
                        pointData.setTime(_time);
                        pointData.setValue(value.toString());
                        equalList.add(pointData);
                    }

                    //把自己再加进去
                    if (i != list.size() - 1) {
                        equalList.add(list.get(i));
                    }
                }

            }

            return equalList;
        } else {
            map.put("period", period);
            String content = httpGet(map, URL_GETHISTSNAP);
            List<PointData> list = json2PointData(content, pointName);

            return list;
        }
    }

    /**
     * 获得历史快照的方法
     *
     * @param pointName
     * @param starTime
     * @param endTime
     * @param period
     * @throws Exception
     */
    public List<PointData> getSnapVals(String pointName, String starTime, String endTime, String period) throws Exception {
        HashMap<String, String> map = new HashMap<>();
        map.put("pointId", pointName);
        map.put("start", ParseUtils.getTimestamp(starTime) + "");
        map.put("end", ParseUtils.getTimestamp(endTime) + "");
        map.put("period", period);
        String content = httpGet(map, URL_GETHISTSNAP);
        return json2PointData(content, pointName);
    }

    /**
     * 获取最大、最小、平均值
     * @param pointCode
     * @param startTime
     * @param endTime
     * @param type
     * @return
     */
    public PointData getStatTypeValue(String pointCode, String startTime, String endTime, String type) {
        int startSecond = ParseUtils.getTimestamp(startTime);
        int endSecond = ParseUtils.getTimestamp(endTime);
        int period = endSecond - startSecond;

        HashMap<String, String> map = new HashMap<>();
        map.put("pointId", pointCode);
        map.put("start", StringUtils.valueOf(startSecond));
        map.put("end", StringUtils.valueOf(endSecond));
        map.put("period", StringUtils.valueOf(period));
        map.put("idxtype", type);
        String content = httpGet(map, URL_GETHISTSTATTYPE);

        PointData result = new PointData();
        result.setValue("0");
        result.setName(pointCode);

        // 解析结果
        if (StringUtils.isNotBlank(content)) {
            try {
                JSONObject jsonObject = JSONObject.parseObject(content);
                boolean success = jsonObject.getBoolean("status");
                if (success) {
                    JSONObject data = (JSONObject) jsonObject.get("data");
                    JSONObject stat = (JSONObject) data.get("stat");
                    JSONObject pointObj = (JSONObject) stat.get(pointCode);
                    JSONObject valueObj = null;
                    if ("max".equals(type)) {
                        valueObj = (JSONObject) pointObj.get("maxValue");
                    } else if ("min".equals(type)) {
                        valueObj = (JSONObject) pointObj.get("minValue");
                    } else {
                        valueObj = (JSONObject) pointObj.get("avgValue");
                    }

                    int timestamp = valueObj.getInteger("tTime");
                    String time = ParseUtils.getDate(timestamp);
                    result.setValue(valueObj.getString("dValue"));
                    result.setTime(time);
                } else {
                    String mesg = jsonObject.getString("mesg");
                    logger.error(mesg);
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(pointCode);
            }
        }
        return result;
    }


    //{"status":true,"mesg":"操作成功","data":{"method":"GetHistSnap","homis_AI00004":[[1599753600,2.26]],"stat":{"homis_AI00004":{"maxValue":{"tTime":1599753600,"dValue":2.26,"status":3},"minValue":{"tTime":1599753600,"dValue":2.26,"status":3},"avgValue":{"tTime":0,"dValue":2.26,"status":0}}}}}
    private List<PointData> json2PointData(String content, String pointName) {
        List<PointData> list = new ArrayList<>();
        if ("".equals(content) || content == null) return list;
        try {
            JSONObject jsonObject = JSONObject.parseObject(content);
            boolean success = jsonObject.getBoolean("status");
            if (success) {
                JSONObject data = (JSONObject) jsonObject.get("data");
                JSONArray array = (JSONArray) data.get(pointName);
                //JSONArray array = (JSONArray) data.getJSONArray(pointName);
                List<String[]> strs = JSONArray.parseArray(array.toJSONString(), String[].class);
                for (String[] str : strs) {
                    int timestamp = Integer.valueOf(str[0]);
                    String value = str[1];
                    String time = ParseUtils.getDate(timestamp);
                    PointData pointData = new PointData(pointName, time, value);
                    list.add(pointData);

                }
            } else {
                String mesg = jsonObject.getString("mesg");
                logger.error(mesg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(pointName);
        } finally {
            return list;
        }
    }


    private String httpGet(Map<String, String> paramMap, String url) {
        String content = "";
        HttpGet get = new HttpGet(url);
        try {
            List<NameValuePair> params = setHttpParams(paramMap);
            String param = URLEncodedUtils.format(params, "UTF-8");
            get.setURI(URI.create(url + "?" + param));
            HttpResponse response = httpClient.execute(get);
            HttpEntity entity = response.getEntity();
            //处理数据
            content = EntityUtils.toString(entity);
        } catch (Exception e) {
            System.out.println("请求异常");
            throw new RuntimeException(e);
        } finally {
            get.abort();
        }
        return content;
    }

    private List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> params = new ArrayList<>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
            params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return params;
    }
}
